// the main gui classes
#pragma once

#include <vector>
#include <string>
#include <list>

#include <scene/SceneManager.h>
#include <base/d3d.h>
#include <gui/GuiControl.h>
#include <gui/GuiInputBox.h>

// Guistate is a collection of controls that are 
// associated (ie on a menu page)
class GuiState  {
public:
   GuiState() {_enabled = true; _draw = true; _priority = 0; _root = new SceneNode();}
   
   // deletes controls
   ~GuiState();

   // Add a control in sorted order (by z value)
   void AddControl(GuiControl * control);

   // Draw's the enabled controls 
   void Draw(Device * device, int mouseX, int mouseY, double tElapsed);

   // updates the controls (called if state is in focus)
   void Update(int mouseX, int mouseY, unsigned long key, double tElapsed);

   // TODO: Loading from a gui setup file (xml?)

   // Is enabled (able to receive and send events) drawing still permitted
   inline bool IsEnabled() {return _enabled;}
   inline void SetEnabled(bool val) {_enabled = val;}

   // Is visible (drawn)
   inline bool IsVisible() {return _draw;}
   inline void SetVisible(bool val) {_draw = val;}

private:
   long _priority;
   bool _enabled;
   bool _draw;

   SceneNode * _root;
   std::list<GuiControl *> _controls;
};

// GUI Controller
//  manages gui states
//  draws gui
//  draws console
class GuiController  {
public:
   GuiController(Device * device);

   // deletes states
   ~GuiController();

   // TODO: LoadGUI(std::string filename);

   // draw the gui:
   //  get input and check mouse collision to determine active controls
   //  send keyboard/mouse input to active states and draw
   void DrawGui(Device * device, double tElapsed);

   // adds a guistate to be rendered
   void AddState(GuiState * state);

   // sets the state in focus (to recieve input)
   void SetFocusState(GuiState * state);

   // Updates the console inputbox
   void UpdateConsole(long key, double tElapsed); 

   // draw the console passed
   void DrawConsole(Device * device, std::list<std::string>& lines, std::list<int> lheight) const;

   // show/hide console
   inline void ShowConsole() {_show_console = true;}
   inline void HideConsole() {_show_console = false;}

private:
   SceneNode * _rootNode;
   std::vector<GuiState *> _states;
   unsigned int _focusState;
   
   // console
   bool _show_console;
   GuiInputBox _consoleInput;
   LPDIRECT3DTEXTURE9 _console_bg;
   long _console_font;

};